from enum import Enum
from typing import Dict, Set, Optional, List
from dataclasses import dataclass
import threading


class ProcessState(Enum):
    STOPPED = "stopped"
    STARTING = "starting"
    RUNNING = "running"
    STOPPING = "stopping"
    FAILED = "failed"


@dataclass
class ProcessInfo:
    name: str
    command: list
    state: ProcessState
    resources: List[int]  # 资源向量
    process: Optional[object] = None
    pid: Optional[int] = None
    display_name: str = ""
    description: str = ""


class SystemState:
    def __init__(self):
        # 当前资源使用状态 [motor, lidar, camera_read, camera_write]
        self.current_resource_usage = [0, 0, 0, 0]
        # 记录每个资源被哪些进程占用
        self.resource_usage_map = {
            0: set(),  # motor
            1: set(),  # lidar
            2: set(),  # camera_read
            3: set()  # camera_write
        }
        self.lock = threading.Lock()

    def get_resource_usage(self) -> List[int]:
        """获取当前资源使用状态"""
        with self.lock:
            return self.current_resource_usage.copy()

    def get_resource_conflicts(self) -> Dict[int, Set[str]]:
        """获取资源冲突信息"""
        with self.lock:
            return {k: v.copy() for k, v in self.resource_usage_map.items()}

    def add_process_resources(self, process_name: str, resources: List[int]):
        """添加进程的资源使用"""
        with self.lock:
            for i, usage in enumerate(resources):
                if usage > 0:
                    self.current_resource_usage[i] += usage
                    self.resource_usage_map[i].add(process_name)

    def remove_process_resources(self, process_name: str, resources: List[int]):
        """移除进程的资源使用"""
        with self.lock:
            for i, usage in enumerate(resources):
                if usage > 0:
                    self.current_resource_usage[i] = max(0, self.current_resource_usage[i] - usage)
                    self.resource_usage_map[i].discard(process_name)

    def check_resource_conflict(self, process_name: str, resources: List[int], exclusive_indices: List[int]) -> tuple:
        """检查资源冲突"""
        with self.lock:
            conflicts = []

            # 1. 检查独占资源冲突（motor, lidar, camera_write）
            for i in exclusive_indices:
                if resources[i] > 0 and self.current_resource_usage[i] > 0:
                    conflicting_processes = list(self.resource_usage_map[i])
                    conflicts.append(f"资源索引{i}被进程 {', '.join(conflicting_processes)} 占用")

            # 2. 检查摄像头读写互斥逻辑
            camera_read_index = 2
            camera_write_index = 3

            # 如果新进程要写摄像头，检查是否有读者
            if resources[camera_write_index] > 0 and self.current_resource_usage[camera_read_index] > 0:
                reading_processes = list(self.resource_usage_map[camera_read_index])
                conflicts.append(f"摄像头正被进程 {', '.join(reading_processes)} 读取，无法写入")

            # 如果新进程要读摄像头，检查是否有写者
            if resources[camera_read_index] > 0 and self.current_resource_usage[camera_write_index] > 0:
                writing_processes = list(self.resource_usage_map[camera_write_index])
                conflicts.append(f"摄像头正被进程 {', '.join(writing_processes)} 写入，无法读取")

            if conflicts:
                return False, f"资源冲突: {'; '.join(conflicts)}"

            return True, "无资源冲突"

    def get_processes_using_resource(self, resource_index: int) -> Set[str]:
        """获取正在使用指定资源的进程列表"""
        with self.lock:
            return self.resource_usage_map[resource_index].copy()

    def clear_all_resources(self):
        """清空所有资源使用状态"""
        with self.lock:
            self.current_resource_usage = [0, 0, 0, 0]
            for resource_set in self.resource_usage_map.values():
                resource_set.clear()